<?php 
use	Workerman\Worker; 
require_once	'./Workerman/Autoloader.php';
require_once	'./mysql/src/Connection.php';

//	初始化一个worker容器，监听1234端口
$worker	=	new	Worker('tcp://0.0.0.0:1234');
/*
 *	注意这里进程数必须设置为1，否则会报端口占用错误
 *	(php	7可以设置进程数大于1，前提是$inner_text_worker->reusePort=true)
 */
$worker->count = 1;

$worker->onConnect = function($connection){
	$connection->send("qing shuru your uid "."\n");
};

//新增加一个属性，用来保存uid到connection的映射 
$worker->uidConnections	= array();
//新增加一个属性，用来保存php到connection的映射 
//$worker->phpConnections	= array();
//	worker进程启动后创建一个text	Worker以便打开一个内部通讯端口
$worker->onWorkerStart	= function($worker){
	//	将db实例存储在全局变量中(也可以存储在某类的静态成员中)
	global $db;
	global $worker;
	$db  = new \Workerman\MySQL\Connection('112.74.84.200','3306','root','Tosky2016', 'xiaomi'); 
	//	开启一个内部端口，方便内部系统推送数据，Text协议格式	文本+换行符
	$inner_text_worker	= new Worker('text://0.0.0.0:5678');
	//该端口有数据发来时，触发函数
	$inner_text_worker->onMessage = function($connection,$buffer){
		//	$data转化成数组格式，里面有uid，表示向那个uid的页面推送数据
		$data = json_decode($buffer,true);
		$uid = $data['uid'];
		$value = $data['value'];
		//通过workerman，向uid的页面推送数据
		$ret = sendMessageByUid($uid,$value."\n");
		//返回推送结果
		//$connection->send($ret?'ok':'fail');
		//保存PHP端的连接信息
		$_SESSION['connection'][$uid] = $connection;
	};
	//	##	执行监听	##
	$inner_text_worker->listen();
};
//当有客户端发来消息时执行的回调函数 
$worker->onMessage = function($connection,$data){
	global $worker;
	global $db;
	//	判断当前客户端是否已经验证,既是否设置了uid
	if(!isset($connection->uid)){
		$data = (string)trim($data);
		if(!is2string($data)){
			$connection->send('uid error'."\n");
			return;
		}else{
			$result = $db->select('uid')->from('workerman')->where('uid= :uid')->bindValues(array('uid'=> $data))->row();
			if($result){
				$connection->send('uid you le'."\n");
				return;
			}else{
				
				$insert['uid'] = $insert2['uid'] = $data;//识别id
				$insert['ip'] = $insert2['ip'] = $connection->getRemoteIp();//客户端ip
				//查询是否重新连接
				$result = $db->select('uid')->from('pot2')->where("ip = '".$insert2['ip']."'")->row();
				$ok2 = true;
				if(!$result){
					$insert2['switch'] = '0';
					$ok2 = $db->insert('pot2')->cols($insert2)->query();
				}else{
					$result2 = $db->select('uid')->from('pot2')->where("uid = '".$insert2['uid']."'")->row();
					if(!$result2){
						$connection->send('uid chu ru cuowu'."\n");
						return;
					}
				}
				$ok1 = $db->insert('workerman')->cols($insert)->query();
				if($ok1 && $ok2){
					//保存uid标识
					$connection->uid = $data;
					/*	保存uid到connection的映射，这样可以方便的通过uid查找connection
					*	实现针对特定uid推送数据
					*/
					$worker->uidConnections[$connection->uid] = $connection;
					$ret = sendMessageByUid($connection->uid,'success your uid is '.$connection->uid."\n");
					//返回推送结果
					echo $ret?'uid success'."\n":'uid chu cuo'."\n";
				}else echo "mysql error";
				echo $data;
			}
		}
	}else{
		$data = (string)trim($data);
		sendMessageToPhp($connection->uid,$data."\n");
		sendMessageByUid($connection->uid,'你发送了'.$data."\n");
	}
	return;
};
//	当有客户端连接断开时
$worker->onClose = function($connection){
	global $worker;
	global $db;
	if(isset($connection->uid)){
		//删除客户端的连接数据
		$result = $db->delete('workerman')->where("uid = $connection->uid")->query();
		if($result>0) echo "删除成功！"."\n";
		else echo "删除失败"."\n";
		//	连接断开时删除映射
		unset($worker->uidConnections[$connection->uid]);
		if(isset($_SESSION['connection'][$connection->uid]))
			unset($_SESSION['connection'][$connection->uid]);
	}
};


//	向所有验证的用户推送数据 
function broadcast($message){
	global	$worker;
	foreach($worker->uidConnections	as	$connection){
		$connection->send($message);
	}
}

//	针对uid推送数据
function sendMessageByUid($uid,	$message){
	global	$worker;
	if(isset($worker->uidConnections["$uid"])){
		$connection	= $worker->uidConnections["$uid"];
		$connection->send($message);
		return	true;
	}
	return	false;
}

//	针对uid推送数据
function sendMessageToPhp($uid,	$message){
	global	$worker;
	if(isset($_SESSION['connection']["$uid"])){
		$connection	= $_SESSION['connection']["$uid"];
		$connection->send($message);
		return	true;
	}
	return	false;
}

/**
 * 判断参数是否为字符串
 * @param mixed $str 要判断的变量
 * @param string $filter 条件,多个逗号分隔,如"c,e,n"(如-> n:数字, c:中文, e:英文)
 * @param string $other 其它字符 (如:_*%)
 */
function is2string($str='',$filter='',$other=''){
    if($str=='')
        return false;
    if(!is_numeric($str) AND !is_string($str))
        return false;
    //正由规则变量
    $match = '';
    //filter 条件
    if($filter!=''){
        $filter = My::explode(',',$filter);
        if(is_array($filter)){
            //英文字母
            if(in_array('e',$filter))
                $match .= 'a-zA-Z';
            //数字
            if(in_array('n',$filter))
                $match .= '0-9';
            //中文
            if(in_array('c',$filter))
                $match .= '\x{4e00}-\x{9fa5}';
        }
    }
    //其它正则特殊字符
    if($other!='')
        $match .= $other;
    //验证正则规则
    if($match!='' AND !preg_match('/^['.$match.']+$/u', $str))
        return false;
    return true;
};
//	运行所有的worker Worker::runAll();
Worker::runAll();
